﻿using System.Text;
using System.Text.RegularExpressions;

namespace CabinetGrid.DeviceDriver.IModules.Impls
{
    public class CommandLineModule : IModule
    {
        private readonly ILogger _logger;
        private readonly ViewModel _viewModel;

        public CommandLineModule( ILoggerFactory loggerFactory, ViewModel viewModel )
        {
            _logger = loggerFactory.CreateLogger( nameof( CommandLineModule ) );
            _viewModel = viewModel;
        }

        public async Task StartAsync( CancellationToken cancellationToken )
        {
            if ( Environment.OSVersion.Platform != PlatformID.Win32NT ) return;

            _ = Task.Factory.StartNew( ( ) =>
            {
                while ( cancellationToken.IsCancellationRequested is false )
                {
                    try
                    {
                        var line = Console.ReadLine( );
                        if ( line.IsNullOrWhiteSpace( ) ) continue;

                        var regex = Regex.Match( line, @"(?<cmd>\w*)\s*(?<args>.*)" );
                        if ( regex.Success is false ) throw new Exception( $"无效的命令行: {line}" );

                        var cmd = regex.Groups["cmd"].Value;
                        var args = new ConfigurationBuilder( ).AddCommandLine( regex.Groups["args"].Value.ToArray( ' ' ) ).Build( );

                        switch ( cmd.ToLower( ) )
                        {
                            case "show":
                                {
                                    var builder = new StringBuilder( );

                                    var str = _viewModel.WebSocketClientList.Select( ( item, index ) => $"WS客户端 [{index + 1}] {item.ConnectionInfo.ClientIpAddress}:{item.ConnectionInfo.ClientPort}, id: {item.ConnectionInfo.Id}" ).ToStringWithNewLine( );
                                    builder.AppendLine( str );
                                    builder.AppendLine( );

                                    str = _viewModel.RFIDUHFReaderList.Select( ( api, index ) => $"读写器 [{index + 1}] {api.ReaderId}\t{api.ReaderState}" ).ToStringWithNewLine( );
                                    builder.AppendLine( str );
                                    builder.AppendLine( );

                                    str = _viewModel.RFIDUHFTagList.Select( ( tag, index ) => $"标签 [{( index + 1 ).ToString( "D4" )}] {tag.Reader}\t{tag.EPC}\t{tag.TID}\t{tag.ScanCount}\t{tag.AntList.Select( i => $"{i.AntNo}:{i.RSSI}:{i.Count}" ).ToStringWithComma( )}" ).ToStringWithNewLine( );
                                    builder.AppendLine( str );
                                    builder.AppendLine( );

                                    ConsoleWirter.Success( builder.ToString( ) );
                                    break;
                                }
                            case "help":
                                {
                                    var builder = new StringBuilder( );

                                    builder.AppendLine( "超高频读写器:\t uhf i=读写器索引 c=扫描次数 a=天线通道号(多个用,分隔) t=定位标签索引号" );
                                    builder.AppendLine( "超高频读写器:\t uhf_locate t=定位标签索引号" );
                                    builder.AppendLine( "高频读写器:\t hf i=读写器索引 c=扫描次数 a=天线通道号(多个用,分隔)" );
                                    builder.AppendLine( "锁控:\t\t locker a=锁板地址 n=锁号" );
                                    builder.AppendLine( "锁控:\t\t locker_query a=锁板地址" );
                                    builder.AppendLine( "发卡器(M1卡):\t m1 b=块号" );
                                    builder.AppendLine( "发卡器(身份证):\t icr" );
                                    builder.AppendLine( );

                                    ConsoleWirter.Debug( builder.ToString( ) );
                                    break;
                                }

                            case "uhf":     // uhf i=0 c=4 a=1,2
                                {
                                    var index = args["i"].ToIntOrDefault( defaultValue: 0 );
                                    var scanCount = args["c"].ToIntOrDefault( defaultValue: 1 );
                                    var antNoList = ( args["a"] ?? "1" ).ToList( ).Select( i => byte.Parse( i ) ).ToArray( );

                                    var api = _viewModel.RFIDUHFReaderList[index];

                                    var sw = System.Diagnostics.Stopwatch.StartNew( );
                                    var tagList = _viewModel.RFIDUHFInventoryScan( reader: api.ReaderId, antNoList, scanCount, includeTID: false );
                                    sw.Stop( );

                                    var builder = new StringBuilder( );

                                    var result = tagList.Select( ( tag, index ) => $"标签 [{( index + 1 ).ToString( "D4" )}] {tag.Reader}\t{tag.EPC}\t{tag.TID}\t{tag.ScanCount}\t{tag.AntList.Select( i => $"{i.AntNo}:{i.RSSI}:{i.Count}" ).ToStringWithComma( )}" )
                                                        .ToStringWithNewLine( );
                                    builder.AppendLine( result );
                                    builder.AppendLine( $"耗时: {sw.Elapsed.TotalSeconds} s" );
                                    builder.AppendLine( );

                                    ConsoleWirter.Success( builder.ToString( ) );
                                    break;
                                }
                            case "uhf_locate":  // uhf_locate t=1
                                {
                                    var index = args["t"].ToIntOrDefault( defaultValue: 1 );

                                    var tag = _viewModel.RFIDUHFTagList[index - 1];

                                    var api = _viewModel.RFIDUHFReaderList.Single( i => i.ReaderId == tag.Reader );
                                    var success = api.Locate( o =>
                                    {
                                        o.AntNoList = tag.AntList.Select( i => (byte)i.AntNo ).ToList( );
                                        o.Data = tag.EPC;
                                        o.DurationMilliseconds = 20 * 1000;
                                    } );
                                    ConsoleWirter.Success( $"点亮标签: {tag.EPC}, success: {success}" );
                                    break;
                                }
                            case "uhf_stop":    // uhf_stop i=0
                                {
                                    var index = args["i"].ToIntOrDefault( defaultValue: 0 );
                                    var api = _viewModel.RFIDUHFReaderList[index];

                                    api.StopInventory( );
                                    ConsoleWirter.Info( $"操作完成" );
                                    break;
                                }

                            case "hf":      // hf i=0 c=4 a=1,2,3,4,5,6,7
                                {
                                    var index = args["i"].ToIntOrDefault( defaultValue: 0 );
                                    var scanCount = args["c"].ToIntOrDefault( defaultValue: 1 );
                                    var antNoList = ( args["a"] ?? "1" ).ToList( ).Select( i => byte.Parse( i ) ).ToArray( );

                                    var api = _viewModel.RFIDHFReaderList[index];

                                    var sw = System.Diagnostics.Stopwatch.StartNew( );
                                    var tagList = _viewModel.RFIDHFInventoryScan( reader: api.ReaderId, antNoList, scanCount, readBlock: true, blockStartIndex: 0, blockCount: 3 );
                                    sw.Stop( );

                                    var builder = new StringBuilder( );

                                    var result = tagList.Select( ( tag, index ) => $"标签 [{( index + 1 ).ToString( "D4" )}] {tag.Reader}\t{tag.UID}\t{tag.BlockData}\t{tag.ScanCount}\t{tag.AntList.Select( i => $"{i.AntNo}:{i.Count}" ).ToStringWithComma( )}" )
                                                        .ToStringWithNewLine( );
                                    builder.AppendLine( result );
                                    builder.AppendLine( $"耗时: {sw.Elapsed.TotalSeconds} s" );
                                    builder.AppendLine( );

                                    ConsoleWirter.Success( builder.ToString( ) );
                                    break;
                                }

                            case "locker":          // locker a=1 n=1,2,3,4,5,6,7
                                {
                                    var addr = args["a"].ToByteOrDefault( defaultValue: 1 );
                                    var noList = ( args["n"] ?? "1,2,3,4,5,6,7,8,9,10" ).ToList( ).Select( i => byte.Parse( i ) ).ToArray( );

                                    foreach ( var no in noList )
                                    {
                                        var success = _viewModel.Locker.Unlock( addr, no );
                                        ConsoleWirter.Success( $"开锁成功: {no}" );

                                        Thread.Sleep( 1000 );
                                    }
                                    break;
                                }
                            case "locker_query":    // locker_query a=1
                                {
                                    var addr = args["a"].ToByteOrDefault( defaultValue: 1 );

                                    var stateList = _viewModel.Locker.QueryState( addr );

                                    var list = stateList.Select( ( data, index ) => $"[{( index + 1 ).ToString( "D2" )}] 锁板: {data.Addr}, 锁号: {data.No}, 状态: {data.State}" );
                                    ConsoleWirter.Info( list.ToStringWithNewLine( ) );
                                    break;
                                }

                            case "m1":  // m1 b=1
                                {
                                    var block = ( args["b"] ?? "0" ).ToIntOrDefault( defaultValue: 0 );

                                    var tagInfo = _viewModel.CardReader.M1Inventory( );
                                    ConsoleWirter.Success( $"标签: {tagInfo.UID}" );

                                    var blockInfo = _viewModel.CardReader.M1ReadBlock( block );
                                    ConsoleWirter.Success( $"标签: {blockInfo.UID}, 块号: {blockInfo.BlockNo}, 数据: {blockInfo.BlockData}" );
                                    break;
                                }
                            case "icr":
                                {
                                    var tagInfo = _viewModel.CardReader.ICRInventory( );
                                    ConsoleWirter.Success( $"身份证UID: {tagInfo.UID}" );
                                    break;
                                }

                            case "test":    // test l=1
                                {
                                    var loop = ( args["l"] ?? "1" ).ToIntOrDefault( defaultValue: 1 );

                                    _viewModel.TestRFIDUHFReaderList( loop );
                                    _viewModel.TestLocker( loop );
                                    _viewModel.TestCardReader( loop );

                                    //_viewModel.AudioService.Ready( Constants.AudioFile.SCAN );

                                    //for ( int i = 0; i < 10; i++ )
                                    //{
                                    //    _viewModel.AudioService.Play( reset: true );
                                    //}

                                    //_viewModel.AudioService.DisposeAll( );
                                    break;
                                }
                            default: throw new Exception( $"无效指令: {line}" );
                        }
                    }
                    catch ( Exception ex )
                    {
                        ConsoleWirter.Error( ex.Message );
                    }
                    finally
                    {
                        Console.WriteLine( );
                    }
                }
            }, cancellationToken );


            _logger.Info( $"注册成功" );
            await Task.CompletedTask;
        }

        public async Task StopAsync( CancellationToken cancellationToken )
        {
            _logger.Info( $"注销成功" );
            await Task.CompletedTask;
        }
    }
}
